package by.kniazhych.core.server.local.data {
	
	import by.kniazhych.core.constants.PeaceType;
	import by.kniazhych.core.constants.UserColor;
	import by.kniazhych.core.data.game.PeacePosition;
	import by.kniazhych.core.server.local.core.IMotion;
	import by.kniazhych.core.server.local.core.Motion;
	import by.kniazhych.core.server.local.events.ServerGameEvent;
	import by.kniazhych.core.server.local.rules.IPlayer;
	import by.vaukalak.core.data.DataBase;
	import flash.errors.IllegalOperationError;
	import flash.events.EventDispatcher;
	
	/**
	 * ...
	 * @author Boutylin Mikhail
	 */
	
	
	
	[Event(name="playerChanged", type="by.kniazhych.core.server.local.events.ServerGameEvent")]
	public class BoardData extends DataBase{
		
		//*
		private var _board:Array = [[11, 9, 10, 14, 13, 12, 9, 10, 11],
									[8, 8, 8, 8, 8, 8, 8, 8, 8],
									[0, 0, 0, 0, 0, 0, 0, 0, 0],
									[0, 0, 0, 0, 0, 0, 0, 0, 0],
									[0, 0, 0, 0, 0, 0, 0, 0, 0],
									[0, 0, 0, 0, 0, 0, 0, 0, 0],
									[0, 0, 0, 0, 0, 0, 0, 0, 0],
									[1, 1, 1, 1, 1, 1, 1, 1, 1],
									[4, 3, 2, 7, 6, 5, 3, 2, 4]];
		
		/*/
		private var _board:Array = [[6, 0, 13, 0, 0, 0, 0, 0, 0],
									[0, 0, 0, 0, 0, 1, 0, 0, 0],
									[0, 0, 0, 0, 0, 0, 0, 0, 0],
									[0, 0, 0, 0, 0, 0, 0, 0, 0],
									[0, 0, 0, 0, 0, 0, 10, 0, 0],
									[0, 0, 0, 0, 0, 0, 0, 1, 0],
									[0, 0, 0, 0, 0, 0, 0, 0, 0],
									[0, 0, 0, 0, 0, 0, 0, 0, 0],
									[0, 0, 0, 0, 0, 0, 0, 0, 0]];
		//*/
		
		
									
		private var _currentPlayer:IPlayer;
		private var _lastMotion:IMotion;
		private var _commands:Vector.<ICommand> = new Vector.<ICommand>();
		private var _gameOver:Boolean;
		private var _tronState:Boolean = false;
		
		private var _lastChangedPeacePosition:PeacePosition;
		private var _lastChangedPeaceType:uint;
		private var _oponentPlayer:IPlayer;
		
		public function BoardData() {
			
		}
		
		//--------------------------------------------------------------------------
		//
		//  PUBLIC METHODS
		//
		//--------------------------------------------------------------------------
		
		public function clone():BoardData {
			throw new IllegalOperationError("clone is deprecated");
			var instanse:BoardData = new BoardData();
			instanse._currentPlayer = this._currentPlayer;
			instanse._board = new Array(this._board.length);
			for (var i:int = 0; i < this._board.length; i++) {
				instanse._board[i] = [];
				(instanse._board[i] as Array).push.apply(null, this._board[i]);
			}
			return instanse;
		}
		
		public function getCellState(p:PeacePosition):uint {
			return _board[p.y][p.x];
		}
		
		public function setCellState(p:PeacePosition, state:uint):void {
			_board[p.y][p.x] = state;
		}
		
		public function test(command:ICommand):void {
			command.execute(_board);
			_commands.push(command);
		}
		
		public function rollBack():void {
			_commands.pop().undo();
		}
		
		public function rollBackAll():void {
			while (_commands.length) {
				rollBack();
			}
		}
		
		public function executeMotion(sP:PeacePosition, fP:PeacePosition):void {
			this.rollBackAll();
			new MotionCommand(sP, fP).execute(_board);
			_lastMotion = new Motion(sP, fP);
			super.dispatchEvent(new ServerGameEvent(ServerGameEvent.MOTION_PROCESSED));
		}
		
		public function getPeacesByType(type:uint):Vector.<PeacePosition> {
			var peaces:Vector.<PeacePosition> = new Vector.<PeacePosition>();
			for (var i:int = 0; i < _board.length; i++) {
				for (var j:int = 0; j < _board[i].length; j++) {
					if (_board[i][j] == type) peaces.push(new PeacePosition(j, i));
				}
			}
			return peaces;
		}
		
		public function getPeacesByColor(color:uint):Vector.<PeacePosition> {
			var positions:Vector.<PeacePosition> = new Vector.<PeacePosition>();
			var figures:Array = (color == UserColor.WHITE ? PeaceType.WHITE_PEACES : PeaceType.BLACK_PEACES);
			for (var i:int = 0; i < _board.length; i++) {
				for (var j:int = 0; j < _board[i].length; j++) {
					if (figures.indexOf(_board[i][j]) != -1) {
						positions.push(new PeacePosition(j,i));
					}
				}
			}
			return positions;
		}
		
		public function changePeace(pos:PeacePosition, type:uint):void {
			_board[pos.y][pos.x] = type;
			_lastChangedPeacePosition = pos;
			_lastChangedPeaceType = type;
			super.dispatchEvent(new ServerGameEvent(ServerGameEvent.PEACE_CHANGED));
		}
		
		public function get shah():Boolean {
			return _currentPlayer.isUnderCheck;
		}
		
		public function get tron():Boolean {
			return _board[4][4] != 0 && !this.rokash;
		}
		
		public function get rokash():Boolean {
			return _currentPlayer.isUnderRokash;
		}
		
		public function endTheGame():void {
			_gameOver = true;
			super.dispatchEvent(new ServerGameEvent(ServerGameEvent.GAME_OVER));
		}
		
		//--------------------------------------------------------------------------
		//
		//  DATA ACSESSORS
		//
		//--------------------------------------------------------------------------
		
		public function get board():Array { return _board; }
		
		public function get currentPlayer():IPlayer { return _currentPlayer; }
		
		public function set currentPlayer(value:IPlayer):void {
			if (_currentPlayer) {
				_oponentPlayer = _currentPlayer;
			}
			_currentPlayer = value;
			
			if (this.tron && this._tronState) _gameOver = true;
			_tronState = this.tron;
			super.dispatchEvent(new ServerGameEvent(ServerGameEvent.PLAYER_CHANGED));
		}
		
		public function get lastMotion():IMotion { return _lastMotion; }
		
		public function get gameOver():Boolean { return _gameOver; }
		
		public function get lastChangedPeacePosition():PeacePosition { return _lastChangedPeacePosition; }
		
		public function get lastChangedPeaceType():uint { return _lastChangedPeaceType; }
		
		public function get opponentPlayer():IPlayer { return _oponentPlayer; }
		
		public function set opponentPlayer(value:IPlayer):void {
			if (_oponentPlayer) throw IllegalOperationError("апанент вызначаецца толькі на старце");
			_oponentPlayer = value;
		}
		
	}

}